# -*- coding: utf-8 -*-
# created on 2016/10/20
from abc import ABCMeta, abstractmethod
from sympy import oo, log, exp, fraction, Interval, S, FiniteSet, sympify, Union
from mathsolver.functions.base import BaseFunction, BaseEq
from mathsolver.functions.hanshu.base import yici_judge, erci_judge


def is_continuous_interval(interval):
    """判断区间是否为连续区间"""
    return isinstance(interval, Interval)


class ElementaryFunction(BaseFunction):
    """初等函数: y = f(x)"""
    __metaclass__ = ABCMeta

    def __init__(self, *args):
        self.tag = ""  # 函数名称
        self.expression = BaseEq(["", ""])  # 解析式
        self.exprSympy = 0
        self.domain = S.Reals  # 定义域
        self.range = S.Reals  # 值域
        # self.monotoneInterval = self.domain   # 单调区间
        self.increaseInterval = []  # 增区间
        self.decreaseInterval = []  # 减区间
        self.fixedPoints = []  # 函数过的定点

        if len(args) > 0 and not self.isXFunction(*args):
            raise ValueError('输入函数类型错误!')

    @abstractmethod
    def isXFunction(self, *args):
        """判断是否为特定类型的函数。X可以代表Linear, Quadratic等"""
        pass

    def setDomain(self, interval=S.Reals):
        """设置函数定义域, 默认为R, 同时更新值域和单调区间
        :return: 设置成功返回True, 否则返回False
        """
        if is_continuous_interval(interval):
            # 更新定义域
            self.domain = interval
            # 更新单调区间
            self.updateMonotoneInterval()
            # 更新值域
            self.updateRange()

    def getDomain(self):
        """返回定义域"""
        return self.domain

    @abstractmethod
    def updateRange(self):
        """计算并更新值域"""
        pass

    @abstractmethod
    def updateMonotoneInterval(self):
        """更新单调区间"""
        pass

    def getRange(self):
        """返回值域"""
        return self.range

    # @abstractmethod
    def printing(self):
        """打印函数全部信息"""
        print_str = "------------------------------------------- \n" + \
                    "%s 的解析式为: %s \n" % (self.tag, self.expression.printing()) + \
                    "定义域为: %s \n" % self.getDomain() + \
                    "值域为: %s \n" % self.getRange()
        print_str += "单调增区间: %s 单调减区间: %s \n" % (Union(self.increaseInterval), Union(self.decreaseInterval))
        return print_str


class LinearFunction(ElementaryFunction):
    """一次函数: y = kx+b"""

    def isXFunction(self, *args):
        """判断是否为一次函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand().simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        eq_x = eq.as_independent(self.symbols[0])[1]
        eq_y = eq.as_independent(self.symbols[1])[1]
        cc = eq - eq_x - eq_y  # cc: coeff_constant, 常数项
        if cc.is_number and yici_judge(eq_x) and yici_judge(eq_y):
            self.tag = "一次函数"
            cx = eq_x.coeff(self.symbols[0])  # cx, x项
            cy = eq_y.coeff(self.symbols[1])  # cy, y项
            self.k = -cx / cy
            self.b = -cc / cy
            self.exprSympy = sympify(self.k * self.symbols[0] + self.b)
            self.expression = BaseEq(["%s" % self.symbols[1], "%s" % (self.k * self.symbols[0] + self.b)])
            # 更新单调区间
            self.updateMonotoneInterval()
            return True
        else:
            return False

    def updateRange(self):
        """更新值域"""
        if self.k > 0:
            range_min = self.exprSympy.subs(self.symbols[0], self.domain.args[0])
            range_max = self.exprSympy.subs(self.symbols[0], self.domain.args[1])
            self.range = Interval(range_min, range_max, self.domain.args[2], self.domain.args[3])
        if self.k < 0:
            range_min = self.exprSympy.subs(self.symbols[0], self.domain.args[1])
            range_max = self.exprSympy.subs(self.symbols[0], self.domain.args[0])
            self.range = Interval(range_min, range_max, self.domain.args[3], self.domain.args[2])

    def updateMonotoneInterval(self):
        """更新单调区间"""
        if self.k > 0:
            self.increaseInterval = [self.domain]
            self.decreaseInterval = []
        else:
            self.increaseInterval = []
            self.decreaseInterval = [self.domain]


class QuadraticLineFunction(ElementaryFunction):
    """二次函数: y = ax^2 + bx + c"""

    def isXFunction(self, *args):
        """判断是否为二次函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand().simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        eq_x = eq.as_independent(self.symbols[0])[1]
        eq_y = eq.as_independent(self.symbols[1])[1]
        cc = eq - eq_x - eq_y  # cc: coeff_constant, 常数项
        if cc.is_number and erci_judge(eq_x) and yici_judge(eq_y):
            self.tag = "二次函数"
            cx2 = eq_x.coeff(self.symbols[0] ** 2)  # cx2, x^2项
            cx = eq_x.coeff(self.symbols[0])  # cx, x项
            cy = eq_y.coeff(self.symbols[1])  # cy, y项
            self.a = -cx2 / cy
            self.openUp = (self.a > 0)
            self.b = -cx / cy
            self.c = -cc / cy
            self.symmetryAxis = - self.b / (2 * self.a)  # 对称轴数值
            self.exprSympy = sympify(self.a * self.symbols[0] ** 2 + self.b * self.symbols[0] + self.c)
            self.expression = BaseEq(["%s" % self.symbols[1], "%s" % self.exprSympy])
            self.updateRange()
            self.updateMonotoneInterval()
            return True
        else:
            return False

    def updateRange(self):
        """计算并更新值域"""
        value_sym_axis = self.exprSympy.subs(self.symbols[0], self.symmetryAxis)
        if self.domain.args[0] == -oo:
            value0 = (oo if self.openUp else -oo)
        else:
            value0 = self.exprSympy.subs(self.symbols[0], self.domain.args[0])
        if self.domain.args[1] == oo:
            value1 = (oo if self.openUp else -oo)
        else:
            value1 = self.exprSympy.subs(self.symbols[0], self.domain.args[1])
        # 判断定义域是否包含对称轴
        if self.symmetryAxis in self.domain:
            if self.openUp:  # 开口向上
                if value0 > value1:
                    self.range = Interval(value_sym_axis, value0, False, self.domain.args[2])
                elif value0 < value1:
                    self.range = Interval(value_sym_axis, value1, False, self.domain.args[3])
                else:  # value0 == value1, 只要定义域有一边为闭区间, 值域就是闭区间, 所以用and
                    self.range = Interval(value_sym_axis, value0, False, self.domain.args[2] and self.domain.args[3])
            else:  # 开口向下
                if value0 < value1:
                    self.range = Interval(value0, value_sym_axis, self.domain.args[2], False)
                elif value0 > value1:
                    self.range = Interval(value1, value_sym_axis, self.domain.args[3], False)
                else:  # 同上
                    self.range = Interval(value0, value_sym_axis, self.domain.args[2] and self.domain.args[3], False)
        else:  # 定义域不包含对称轴
            if value0 < value1:
                self.range = Interval(value0, value1, self.domain.args[2], self.domain.args[3])
            else:
                self.range = Interval(value1, value0, self.domain.args[3], self.domain.args[2])
                # TODO: 是否需要考虑value0 == value1 ?

    def updateMonotoneInterval(self):
        """更新单调区间"""
        left, right, lopen, ropen = self.domain.args
        # 判断定义域是否包含对称轴
        if self.symmetryAxis in self.domain:
            if self.openUp:  # 开口向上 TODO: 下面4行的True/False决定是否要把对称轴加到区间里
                self.decreaseInterval = [Interval(left, self.symmetryAxis, lopen, True)]
                self.increaseInterval = [Interval(self.symmetryAxis, right, True, ropen)]
            else:  # 开口向下
                self.increaseInterval = [Interval(left, self.symmetryAxis, lopen, True)]
                self.decreaseInterval = [Interval(self.symmetryAxis, right, True, ropen)]
        else:  # 定义域不包含对称轴
            if (self.openUp and right < self.symmetryAxis) or (not self.openUp and left > self.symmetryAxis):
                self.decreaseInterval = [self.domain]
                self.increaseInterval = []
            else:
                self.increaseInterval = [self.domain]
                self.decreaseInterval = []


class InverseProportionalFunction(ElementaryFunction):
    """反比例函数: y = k/x"""

    def isXFunction(self, *args):
        """判断是否为反比例函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand().simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        # TODO: 假设输入为最基本的y = k/x形式。其他形式, 如k/x = y, x*y = k等, 需要加入新的判断
        self.k = f2.coeff(1 / self.symbols[0])
        if f2.is_Mul and self.k.is_number:
            self.tag = "反比例函数"
            self.exprSympy = f2
            self.expression = args[0]
            self.center = (0, 0)  # 对称中心
            self.domain = FiniteSet(0).complement(S.Reals)
            # 更新单调区间
            self.updateMonotoneInterval()
            self.updateRange()
            return True
        else:
            return False

    def updateRange(self):
        """更新值域"""
        ranges = S.EmptySet
        for monoInt in self.increaseInterval:
            if monoInt.args[0] == 0:
                value0 = -oo
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == 0:
                value1 = oo
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value0, value1, monoInt.args[2], monoInt.args[3])
            ranges = ranges.union(subrange)
        for monoInt in self.decreaseInterval:
            if monoInt.args[0] == 0:
                value0 = oo
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == 0:
                value1 = -oo
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value1, value0, monoInt.args[3], monoInt.args[2])
            ranges = ranges.union(subrange)
        self.range = ranges

    def updateMonotoneInterval(self):
        """更新单调区间"""
        monotone_interval = []
        if is_continuous_interval(self.domain):
            monotone_interval.append(self.domain)
        else:
            for inte in self.domain.args:
                monotone_interval.append(inte)
        if self.k > 0:
            self.increaseInterval = []
            self.decreaseInterval = monotone_interval
        else:
            self.increaseInterval = monotone_interval
            self.decreaseInterval = []


class PowerFunction(ElementaryFunction):
    """幂函数: y = x^a"""

    def isXFunction(self, *args):
        """判断是否为幂函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand()  # .simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        sym = self.symbols[0]
        if f2.is_Pow and (f2.args[0] == sym and f2.args[1].is_number):
            self.tag = "幂函数"
            self.a = f2.args[1]  # y = x^a
            self.exprSympy = f2
            self.expression = args[0]
            if self.a.is_integer:
                # 当a为整数时，
                if self.a > 0:
                    self.fixedPoints.append((0, 0))
                    self.fixedPoints.append((1, 1))
                    # if self.a % 2 != 0:  # 当a为正奇数时，图像在定义域为R内单调递增
                    #     self.domain = S.Reals
                elif self.a < 0:
                    self.fixedPoints.append((1, 1))
                    self.domain = FiniteSet(0).complement(S.Reals)  # 定义域为{x∈R|x≠0}
                else:
                    self.domain = FiniteSet(0).complement(S.Reals)  # 定义域为{x∈R|x≠0}
            else:
                # 当a为分数时，
                # sympy中正数1/q为pow, p/q为mul
                # 首先需要解析出p q
                if self.a < 0:
                    # 负数均为mul
                    minus_a = - self.a
                    if minus_a.is_Mul:
                        self.p = -minus_a.args[0]
                        self.q = 1 / minus_a.args[1]
                    elif minus_a.is_Rational:
                        self.p = -minus_a.p
                        self.q = minus_a.q
                    else:
                        self.p = -1
                        self.q = 1 / minus_a
                elif self.a.is_Mul:
                    self.p = self.a.args[0]
                    self.q = 1 / self.a.args[1]
                else:
                    self.p = 1
                    self.q = 1 / self.a
                # 然后确定定义域
                if self.a > 0 and self.q % 2 == 0:
                    self.domain = Interval(0, oo, False, True)
                elif self.a < 0 and self.q % 2 == 0:
                    self.domain = Interval(0, oo, True, True)
                if self.a > 0 and self.q % 2 == 1:
                    self.domain = S.Reals
                elif self.a < 0 and self.q % 2 == 1:
                    self.domain = FiniteSet(0).complement(S.Reals)  # 定义域为{x∈R|x≠0}

            self.updateMonotoneInterval()
            self.updateRange()
            return True
        else:
            return False

    def updateMonotoneInterval(self):
        """更新单调区间"""
        monotone_interval = []
        if is_continuous_interval(self.domain):
            monotone_interval.append(self.domain)
        else:
            for inte in self.domain.args:
                monotone_interval.append(inte)

        if self.a.is_integer:  # 一、当a为整数时，a的正负性和奇偶性决定了函数的单调性
            if self.a > 0 and self.a % 2 == 1:  # ①当a为正奇数时，图像在定义域为R内单调递增
                self.increaseInterval = monotone_interval
                self.decreaseInterval = []
            elif self.a > 0 and self.a % 2 == 0:  # ②当a为正偶数时，图像在定义域为第二象限内单调递减，在第一象限内单调递增
                self.increaseInterval = [Interval(0, oo, False, True)]
                self.decreaseInterval = [Interval(-oo, 0, True, False)]
            elif self.a < 0 and self.a % 2 == 1:  # ③当a为负奇数时，图像在第一三象限各象限内单调递减
                self.increaseInterval = []
                self.decreaseInterval = monotone_interval
            else:  # ④当a为负偶数时，图像在第二象限上单调递增，在第一象限内单调递减
                self.increaseInterval = [Interval(-oo, 0, True, True)]
                self.decreaseInterval = [Interval(0, oo, True, True)]
        else:  # 二、当a为分数时，a的正负性和分母的奇偶性决定了函数的单调性

            if self.a > 0 and self.q % 2 == 0:  # ①当a>0，分母为偶数时，函数在第一象限内单调递增；
                self.increaseInterval = monotone_interval
                self.decreaseInterval = []
            elif self.a < 0 and self.q % 2 == 0:  # ③当a<0，分母为偶数时，函数在第一象限内单调递减
                self.increaseInterval = []
                self.decreaseInterval = monotone_interval
            if self.a > 0 and self.q % 2 == 1:  # ②当a>0，分母为奇数时，函数在第一、三象限各象限内单调递增
                self.increaseInterval = monotone_interval
                self.decreaseInterval = []
            elif self.a < 0 and self.q % 2 == 1:  # ④当a<0，分母为奇数时，函数在第一、三象限各象限内单调递减
                self.increaseInterval = []
                self.decreaseInterval = monotone_interval

    def updateRange(self):
        """更新值域"""
        if self.a.is_integer:  # 一、当a为整数时，a的正负性和奇偶性决定了函数的单调性
            if self.a > 0 and self.a % 2 == 1:  # ①当a为正奇数时，值域为R
                self.range = S.Reals
            elif self.a > 0 and self.a % 2 == 0:  # ②当a为正偶数时
                self.range = Interval(0, oo, False, True)
            elif self.a < 0 and self.a % 2 == 1:  # ③当a为负奇数时，
                self.range = FiniteSet(0).complement(S.Reals)
            else:  # ④当a为负偶数时，
                self.range = Interval(0, oo, True, True)
        else:  # 二、当a为分数时，a的正负性和分母的奇偶性决定了函数的单调性

            if self.a > 0 and self.q % 2 == 0:  # ①当a>0，分母为偶数时
                self.range = Interval(0, oo, False, True)
            elif self.a < 0 and self.q % 2 == 0:  # ③当a<0，分母为偶数时
                self.range = Interval(0, oo, True, True)
            if self.a > 0 and self.q % 2 == 1:  # ②当a>0，分母为奇数时
                if self.p % 2 == 1:
                    self.range = S.Reals
                elif self.p % 2 == 0:
                    self.range = Interval(0, oo, False, True)
            elif self.a < 0 and self.q % 2 == 1:  # ④当a<0，分母为奇数时
                if self.p % 2 == 1:  # 分子负奇数
                    self.range = FiniteSet(0).complement(S.Reals)
                elif self.p % 2 == 0:  # 分子负偶数
                    self.range = Interval(0, oo, True, True)


class ExponentialFunction(ElementaryFunction):
    """指数函数: y = a^x"""

    def isXFunction(self, *args):
        """
        判断是否为指数函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand()  # .simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        # TODO: 假设输入为最基本的y = a**x形式。其他形式, 如a**x = yk等, 需要加入新的判断
        sym = self.symbols[0]
        if f2.is_Pow and (f2.args[1] == sym or f2.args[1] == -sym):
            if f2.args[1] == sym:
                self.a = f2.args[0]
                self.exprSympy = f2
                self.expression = args[0]
            else:
                self.a = 1 / f2.args[0]
                self.exprSympy = self.a ** sym
                self.expression = BaseEq(["%s" % (self.symbols[1]), "%s" % (self.exprSympy)])
            self.tag = "指数函数"
            self.fixedPoints.append((0, 1))  # 指数函数过定点(0, 1)
            self.updateMonotoneInterval()
            self.updateRange()
            return True
        else:
            return False

    def updateRange(self):
        """更新值域"""
        ranges = S.EmptySet
        for monoInt in self.increaseInterval:
            value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == oo:
                value1 = oo
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value0, value1, monoInt.args[2], monoInt.args[3])
            ranges = ranges.union(subrange)
        for monoInt in self.decreaseInterval:
            if monoInt.args[0] == -oo:
                value0 = oo
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value1, value0, monoInt.args[3], monoInt.args[2])
            ranges = ranges.union(subrange)
        self.range = ranges

    def updateMonotoneInterval(self):
        """更新单调区间"""
        monotone_interval = []
        if is_continuous_interval(self.domain):
            monotone_interval.append(self.domain)
        else:
            for inte in self.domain.args:
                monotone_interval.append(inte)
        if self.a > 1:
            self.increaseInterval = monotone_interval
            self.decreaseInterval = []

        else:
            self.increaseInterval = []
            self.decreaseInterval = monotone_interval


class LogarithmicFunction(ElementaryFunction):
    """对数函数: y = log_a^x"""

    def isXFunction(self, *args):
        """
        判断是否为对数函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand().simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        # TODO: 假设输入为最基本的y = log(x, a)形式。其他形式, 如log(x, a) = y等, 需要加入新的判断
        sym = self.symbols[0]
        if f2.is_Mul:
            c, f = f2.as_independent(sym)
        if c.is_real and isinstance(f, log) and len(f.args[0].free_symbols) > 0:
            if c.is_number:  # log(x, 0.5) a为小数的情况, sympy会把1/log(0.5)求出来
                self.a = exp(1 / c)
            else:
                self.a = (1 / c).args[0]
            self.tag = "对数函数"
            self.exprSympy = f2
            self.expression = args[0]
            self.fixedPoints.append((1, 0))  # 指数函数过定点(1, 0)
            self.domain = Interval(0, oo, True, True)
            self.updateMonotoneInterval()
            self.updateRange()
            return True
        else:
            return False

    def updateRange(self):
        """更新值域(根据单调区间)"""
        ranges = S.EmptySet
        for monoInt in self.increaseInterval:
            if monoInt.args[0] == 0:  # 需要专门处理oo的情况, subs有时候会出错, 或者输出inf而不是oo
                value0 = -oo
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == oo:
                value1 = oo
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value0, value1, monoInt.args[2], monoInt.args[3])
            ranges = ranges.union(subrange)
        for monoInt in self.decreaseInterval:
            if monoInt.args[0] == 0:
                value0 = oo
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == oo:
                value1 = -oo
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value1, value0, monoInt.args[3], monoInt.args[2])
            ranges = ranges.union(subrange)
        self.range = ranges

    def updateMonotoneInterval(self):
        """更新单调区间"""
        monotone_interval = []
        if is_continuous_interval(self.domain):
            monotone_interval.append(self.domain)
        else:
            for inte in self.domain.args:
                monotone_interval.append(inte)
        if self.a > 1:
            self.increaseInterval = monotone_interval
            self.decreaseInterval = []

        else:
            self.increaseInterval = []
            self.decreaseInterval = monotone_interval


class FractionalFunction(ElementaryFunction):
    """(一次)分式函数: y = (a*x+b)/(m*x+n)"""

    def isXFunction(self, *args):
        """
        判断是否为一次分式函数
        :param args: BaseEq
        :return: bool
        """
        f1, f2 = args[0].sympify()
        eq = (f1 - f2).expand().simplify()  # eq: 一般式
        self.symbols = list(eq.free_symbols)
        if len(self.symbols) != 2:
            return False
        numerator, denominator = fraction(f2)
        if yici_judge(numerator) and yici_judge(denominator):
            self.tag = "一次分式函数"
            self.exprSympy = f2
            self.expression = args[0]
            self.a = numerator.coeff(self.symbols[0])
            self.b = numerator.as_independent(self.symbols[0])[0]
            self.m = denominator.coeff(self.symbols[0])
            self.n = denominator.as_independent(self.symbols[0])[0]
            self.centerx = -self.n / self.m
            self.centery = self.a / self.m
            self.k = (self.b - self.a * self.n / self.m) / self.m
            self.domain = FiniteSet(self.centerx).complement(S.Reals)
            # 对称中心
            self.center = (self.centerx, self.centery)  # 对称中心
            # 更新单调区间
            self.updateMonotoneInterval()
            # 更新值域
            self.updateRange()
            return True
        else:
            return False

    def updateRange(self):
        """更新值域"""
        ranges = S.EmptySet
        for monoInt in self.increaseInterval:  # 处理增区间
            if monoInt.args[0] == self.centerx:
                value0 = -oo
            elif monoInt.args[0] == -oo:
                value0 = self.centery
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == self.centerx:
                value1 = oo
            elif monoInt.args[1] == oo:
                value1 = self.centery
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value0, value1, monoInt.args[2], monoInt.args[3])
            ranges = ranges.union(subrange)
        for monoInt in self.decreaseInterval:  # 处理减区间
            if monoInt.args[0] == self.centerx:
                value0 = oo
            elif monoInt.args[0] == -oo:
                value0 = self.centery
            else:
                value0 = self.exprSympy.subs(self.symbols[0], monoInt.args[0])
            if monoInt.args[1] == self.centerx:
                value1 = -oo
            elif monoInt.args[1] == oo:
                value1 = self.centery
            else:
                value1 = self.exprSympy.subs(self.symbols[0], monoInt.args[1])
            subrange = Interval(value1, value0, monoInt.args[3], monoInt.args[2])
            ranges = ranges.union(subrange)
        self.range = ranges

    def updateMonotoneInterval(self):
        """更新单调区间"""
        monotone_interval = []
        if is_continuous_interval(self.domain):
            monotone_interval.append(self.domain)
        else:
            for inte in self.domain.args:
                monotone_interval.append(inte)
        if self.k > 0:
            self.increaseInterval = []
            self.decreaseInterval = monotone_interval
        else:
            self.increaseInterval = monotone_interval
            self.decreaseInterval = []


if __name__ == '__main__':
    pass
